/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.housekeeper.service.impl;

import com.huawei.housekeeper.constants.DeletedFlagEnum;
import com.huawei.housekeeper.enums.ErrorCode;
import com.huawei.housekeeper.exception.Assert;
import com.huawei.housekeeper.utils.CopyUtils;
import com.huawei.housekeeper.utils.TokenUtil;
import com.huawei.housekeeper.controller.request.CreateServiceSelectionDto;
import com.huawei.housekeeper.controller.request.CreateServiceSpecificationDto;
import com.huawei.housekeeper.controller.request.DeleteServiceSkuDto;
import com.huawei.housekeeper.controller.request.DeleteSpecificationDto;
import com.huawei.housekeeper.controller.request.GetSkuDetailBySkuIdDto;
import com.huawei.housekeeper.controller.request.UpdateSeriviceSkuDto;
import com.huawei.housekeeper.controller.response.GetServiceSelectionByServiceIdVo;
import com.huawei.housekeeper.controller.response.ServiceSkuInfoRespVo;
import com.huawei.housekeeper.dao.entity.HousekeeperService;
import com.huawei.housekeeper.dao.entity.ServiceOption;
import com.huawei.housekeeper.dao.entity.ServiceSelection;
import com.huawei.housekeeper.dao.entity.ServiceSku;
import com.huawei.housekeeper.dao.entity.ServiceSpecification;
import com.huawei.housekeeper.dao.mapper.HousekeeperServiceMapper;
import com.huawei.housekeeper.dao.mapper.ServiceOptionMapper;
import com.huawei.housekeeper.dao.mapper.ServiceSelectionMapper;
import com.huawei.housekeeper.dao.mapper.ServiceSkuMapper;
import com.huawei.housekeeper.dao.mapper.ServiceSpecificationMapper;
import com.huawei.housekeeper.service.IHouseKeeperServiceSkuService;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 功能描述 服务功能类
 *
 * @author jWX1116205
 * @since 2022-01-17
 */
@Slf4j
@Service
public class HouseKeeperServiceSkuServiceImpl implements IHouseKeeperServiceSkuService {
    @Autowired
    private HousekeeperServiceMapper housekeeperServiceMapper;

    @Autowired
    private ServiceOptionMapper serviceOptionMapper;

    @Autowired
    private ServiceSelectionMapper serviceSelectionMapper;

    @Autowired
    private ServiceSkuMapper serviceSkuMapper;

    @Autowired
    private ServiceSpecificationMapper serviceSpecificationMapper;

    @Autowired
    private TokenUtil tokenUtil;

    /**
     * 创建服务规格
     *
     * @param createServiceSpecificationDto
     * @return {@link int}
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createHousekeeperServiceSpecification(CreateServiceSpecificationDto createServiceSpecificationDto) {
        ServiceSpecification specification = new ServiceSpecification();
        CopyUtils.copyProperties(createServiceSpecificationDto, specification);
        specification.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        Map<String, Object> params = new HashMap<>();
        params.put("name", createServiceSpecificationDto.getName());
        params.put("serviceId", createServiceSpecificationDto.getServiceId());
        int countSpecName = serviceSpecificationMapper.getCountByServiceSpecificationName(params);
        Assert.isTrue(countSpecName == 0, ErrorCode.SELECT_REPEATED.getCode(),
            ErrorCode.SELECT_REPEATED.getMessage());

        // 1.服务规格表
        serviceSpecificationMapper.insert(specification);

        // 2.规格选项表
        List<ServiceOption> serviceOptionList = new ArrayList<>();
        createServiceSpecificationDto.getServiceOptionList().forEach(option -> {
            Assert.notNull(specification.getId(), ErrorCode.SPECIFICATION_SELECT_EMPTY.getCode(),
                ErrorCode.SPECIFICATION_SELECT_EMPTY.getMessage());
            ServiceOption serviceOption = new ServiceOption();
            serviceOption.setSpecificationId(specification.getId());
            serviceOption.setName(option);
            serviceOption.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
            serviceOptionList.add(serviceOption);
        });
        serviceOptionMapper.insertBatch(serviceOptionList);
        return specification.getId();
    }

    /**
     * 验证该服务组合选项是否已存在，组合存在,报服务选集已存在异常
     *
     * @param createServiceSelectionDto
     */
    private void checkServiceSelectionOptionIsRepeated(CreateServiceSelectionDto createServiceSelectionDto) {
        // 根据服务Id查询该服务下的服务选集
        List<GetServiceSelectionByServiceIdVo> serviceSelectionByServiceIdVos
            = serviceSelectionMapper.getServiceSelectionVoListByServiceId(createServiceSelectionDto.getServiceId());
        if (CollectionUtils.isEmpty(serviceSelectionByServiceIdVos)) {
            return;
        }

        // 将服务选集按skuId分组，获取每个sku对应的规格选项 {skuId:[optionIds]}
        Map<Long, List<Long>> getOptionIdGroupBySkuIdMap = serviceSelectionByServiceIdVos.stream()
            .collect(Collectors.groupingBy(GetServiceSelectionByServiceIdVo::getSkuId,
                Collectors.mapping(GetServiceSelectionByServiceIdVo::getOptionId, Collectors.toList())));

        // 本次校验是基于创建的情景，插入服务选集之前校验该服务的所有的sku的规格选项的组合列表
        for (Map.Entry<Long, List<Long>> listEntry : getOptionIdGroupBySkuIdMap.entrySet()) {
            // 参数的组合optionIds，比如[1,2,3],listEntry.getValue()=[1,2,3],如果组合相同，repeatIdCheckList为空，说明存在冲突
            // repeatIdCheckList不为空，则可以后续的保存操作
            List<Long> repeatIdCheckList = listEntry.getValue()
                .stream()
                .filter(item -> !createServiceSelectionDto.getOptionIds().contains(item))
                .collect(Collectors.toList());

            // 验证repeatIdCheckList不为空，放行，为空抛出异常,报服务选集已存在异常
            Assert.notEmpty(repeatIdCheckList, ErrorCode.SELECT_REPEATED.getCode(),
                ErrorCode.SELECT_REPEATED.getMessage());
        }
    }

    /**
     * 创建服务选集和Sku
     *
     * @param createServiceSelectionDto
     * @return {@link String}
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String createHousekeeperServiceSelection(CreateServiceSelectionDto createServiceSelectionDto) {
        // 验证该服务组合选项是否已存在
        checkServiceSelectionOptionIsRepeated(createServiceSelectionDto);
        StringBuilder selectionIds = new StringBuilder();

        // 创建ServiceSku
        ServiceSku serviceSku = new ServiceSku();
        serviceSku.setServiceId(createServiceSelectionDto.getServiceId());
        serviceSku.setPrice(createServiceSelectionDto.getPrice());
        serviceSku.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        serviceSkuMapper.insert(serviceSku);

        // 插入服务选集
        List<ServiceSelection> serviceSelectionList = new ArrayList<>();
        createServiceSelectionDto.getOptionIds().forEach(optionId -> {
            ServiceSelection selectionObj = new ServiceSelection();
            selectionObj.setSkuId(serviceSku.getId());
            selectionObj.setOptionId(optionId);
            selectionObj.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
            serviceSelectionList.add(selectionObj);
            selectionIds.append(optionId + ",");
        });

        // 注意sku必须要存在服务选集
        Assert.notEmpty(serviceSelectionList, ErrorCode.SERVICE_SELECT_EMPTY.getCode(),
            ErrorCode.SERVICE_SELECT_EMPTY.getMessage());
        serviceSelectionMapper.insertBatch(serviceSelectionList);
        return selectionIds.toString().substring(0, selectionIds.toString().lastIndexOf(","));
    }

    /**
     * 删除服务规格
     *
     * @param deleteServiceSpecificationDto
     * @return {@link int}
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long deleteHousekeeperServiceSpecification(DeleteSpecificationDto deleteServiceSpecificationDto) {
        Long specificationId = deleteServiceSpecificationDto.getSpecId();

        Assert.notNull(serviceSpecificationMapper.selectById(specificationId),
            ErrorCode.SPECIFICATION_NOT_EXIST.getCode(), ErrorCode.SPECIFICATION_NOT_EXIST.getMessage());
        // 1.删除规格
        ServiceSpecification specificationDel = new ServiceSpecification();
        specificationDel.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
        specificationDel.setId(specificationId);
        serviceSpecificationMapper.updateById(specificationDel);

        // 2.删除规格选项
        LambdaQueryWrapper<ServiceOption> queryOption = Wrappers.lambdaQuery();
        queryOption.eq(ServiceOption::getSpecificationId, specificationId);
        queryOption.eq(ServiceOption::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceOption> serviceOptionList = serviceOptionMapper.selectList(queryOption);
        ServiceOption updateOption = new ServiceOption();
        updateOption.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
        serviceOptionMapper.update(updateOption, queryOption);

        // 3.删除可选服务的OptionId
        if (!CollectionUtils.isEmpty(serviceOptionList)) {
            List<Long> optionIds = serviceOptionList.stream()
                .collect(Collectors.mapping(ServiceOption::getId, Collectors.toList()));

            // 确定是否删除该skuId：改sku下的所有的服务选项被删除
            List<Long> deletedSkuList = getDeleteSkuId(optionIds);
            if (!CollectionUtils.isEmpty(deletedSkuList)) {
                LambdaQueryWrapper<ServiceSku> updateWrapper = Wrappers.lambdaQuery();
                updateWrapper.in(ServiceSku::getId, deletedSkuList);
                ServiceSku updateObj = new ServiceSku();
                updateObj.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
                serviceSkuMapper.update(updateObj, updateWrapper);
            }
            serviceSelectionMapper.deleteByOptionIds(optionIds, tokenUtil.getUserNameFromHeader());
        }
        return specificationId;
    }

    /**
     * 删除规格时，注意删除对应的sku的选集记录，若sku对应的规格选项都删除了，对应的规格也要级联删除
     *
     * @param optionIds
     * @return {@link List< Long>}
     * @throws
     */
    private List<Long> getDeleteSkuId(List<Long> optionIds) {
        List<Long> deletedSkuList = Lists.newArrayList();
        // 通过optionId查找所有关联的skuId
        LambdaQueryWrapper<ServiceSelection> selectionQuery = Wrappers.lambdaQuery();
        selectionQuery.select(ServiceSelection::getId, ServiceSelection::getOptionId, ServiceSelection::getSkuId);
        selectionQuery.in(ServiceSelection::getOptionId, optionIds);
        selectionQuery.eq(ServiceSelection::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSelection> selectionSkuList = serviceSelectionMapper.selectList(selectionQuery);

        // 删除服务规格可能导致对应的optionId选集表记录为空
        if (CollectionUtils.isEmpty(selectionSkuList)) {
            return deletedSkuList;
        }
        List<Long> skuIds = selectionSkuList.stream()
            .collect(Collectors.mapping(ServiceSelection::getSkuId, Collectors.toList()));
        Map<Long, List<ServiceSelection>> groupBySkuIdMapFromDeleted = selectionSkuList.stream()
            .collect(Collectors.groupingBy(ServiceSelection::getSkuId, Collectors.toList()));

        // 根据skuId查找所有未删除的服务选项
        LambdaQueryWrapper<ServiceSelection> selectionQueryBySkuId = Wrappers.lambdaQuery();
        selectionQueryBySkuId.select(ServiceSelection::getId, ServiceSelection::getOptionId,
            ServiceSelection::getSkuId);
        selectionQueryBySkuId.in(ServiceSelection::getSkuId, skuIds);
        selectionQueryBySkuId.eq(ServiceSelection::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSelection> selectionContainOthersList = serviceSelectionMapper.selectList(selectionQueryBySkuId);
        Map<Long, List<ServiceSelection>> groupBySkuIdMap = selectionContainOthersList.stream()
            .collect(Collectors.groupingBy(ServiceSelection::getSkuId, Collectors.toList()));
        groupBySkuIdMap.forEach((skuId, selectionList) -> {
            List<Long> selectionDeleteds = groupBySkuIdMapFromDeleted.get(skuId)
                .stream()
                .collect(Collectors.mapping(ServiceSelection::getOptionId, Collectors.toList()));
            List<ServiceSelection> skuContainOtherSelections = selectionList.stream()
                .filter(sel -> !selectionDeleteds.contains(sel.getOptionId()))
                .collect(Collectors.toList());
            if (CollectionUtils.isEmpty(skuContainOtherSelections)) {
                deletedSkuList.add(skuId);
            }
        });
        return deletedSkuList;
    }

    /**
     * 更新服务Sku，需注意更新的时候，修改服务选集的时候，可能存在服务选集相同，但是价格不同的异常情况
     *
     * @param updateSeriviceSkuDto
     * @return {@link int}
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long updateSeriviceSku(UpdateSeriviceSkuDto updateSeriviceSkuDto) {
        // 1.修改Sku
        ServiceSku serviceSku = new ServiceSku();
        serviceSku.setId(updateSeriviceSkuDto.getSkuId());
        serviceSku.setPrice(updateSeriviceSkuDto.getPrice());
        serviceSkuMapper.updateById(serviceSku);
        if (CollectionUtils.isEmpty(updateSeriviceSkuDto.getOptionProperties())) {
            return serviceSku.getId();
        }

        // 2.修改Sku对应的optionId，修改之前需要校验本次修改的optionId组合是否和其它Sku组合是否存在冲突
        // 注意更新的时候和保存的区别，更新的时候要排除该sku自己已存在的组合
        checkServiceSelectionOptionIsRepeated(updateSeriviceSkuDto, serviceSku);

        // 更新可选服务规格选项排列组合
        updateSeriviceSkuDto.getOptionProperties().forEach(optionProperty -> {
            ServiceSelection serviceSelection = new ServiceSelection();
            serviceSelection.setId(optionProperty.getSelectionId());
            serviceSelection.setOptionId(optionProperty.getOptionId());
            serviceSelectionMapper.updateById(serviceSelection);
        });
        return serviceSku.getId();
    }

    /**
     * 修改之前需要校验本次修改的optionId组合是否和其它Sku组合是否存在冲突
     * 注意更新的时候和保存的区别，更新的时候要排除该sku自己已存在的组合
     *
     * @param updateSeriviceSkuDto
     * @param serviceSku
     */
    private void checkServiceSelectionOptionIsRepeated(UpdateSeriviceSkuDto updateSeriviceSkuDto,
        ServiceSku serviceSku) {
        // 根据skuId 查询该skuId的服务选集
        LambdaQueryWrapper<ServiceSelection> querySelection = Wrappers.lambdaQuery();
        querySelection.eq(ServiceSelection::getSkuId, updateSeriviceSkuDto.getSkuId());
        querySelection.eq(ServiceSelection::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSelection> serviceSelections = serviceSelectionMapper.selectList(querySelection);

        List<Long> dbOptionIdList = serviceSelections.stream()
            .map(ServiceSelection::getOptionId)
            .collect(Collectors.toList());
        List<Long> optionIdsOfParam = updateSeriviceSkuDto.getOptionProperties()
            .stream()
            .collect(Collectors.mapping(UpdateSeriviceSkuDto.OptionProperty::getOptionId, Collectors.toList()));
        List<Long> paramDifferOptionIds = optionIdsOfParam.stream()
            .filter(item -> !dbOptionIdList.contains(item))
            .collect(Collectors.toList());

        // 规格选项没有修改
        if (CollectionUtils.isEmpty(paramDifferOptionIds)) {
            return;
        }

        // 根据serviceId查询该服务所在的sku列表
        LambdaQueryWrapper<ServiceSku> querySkuList = Wrappers.lambdaQuery();
        querySkuList.eq(ServiceSku::getServiceId, serviceSku.getServiceId());
        querySkuList.eq(ServiceSku::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSku> serviceSkuList = serviceSkuMapper.selectList(querySkuList);

        // 查询该sku所在的服务下的所有的 服务选集
        List<Long> skuIds = serviceSkuList.stream().map(ServiceSku::getId).collect(Collectors.toList());
        LambdaQueryWrapper<ServiceSelection> querySelection2 = Wrappers.lambdaQuery();
        querySelection2.in(ServiceSelection::getSkuId, skuIds);
        querySelection2.eq(ServiceSelection::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSelection> slectionsByServceIdFromSku = serviceSelectionMapper.selectList(querySelection2);
        List<ServiceSelection> otherServiceSelectionOfService = slectionsByServceIdFromSku.stream()
            .filter(item -> !updateSeriviceSkuDto.getSkuId().equals(item.getSkuId()))
            .collect(Collectors.toList());

        // 该服务只存在一个sku
        if (CollectionUtils.isEmpty(otherServiceSelectionOfService)) {
            return;
        }

        // 将服务选集按skuId分组，获取每个sku对应的规格选项 {skuId:[optionIds]}
        Map<Long, List<Long>> getOptionIdGroupBySkuIdMap = otherServiceSelectionOfService.stream()
            .collect(Collectors.groupingBy(ServiceSelection::getSkuId,
                Collectors.mapping(ServiceSelection::getOptionId, Collectors.toList())));
        for (Map.Entry<Long, List<Long>> listEntry : getOptionIdGroupBySkuIdMap.entrySet()) {
            List<Long> repeatIdCheckList = listEntry.getValue()
                .stream()
                .filter(itemOptionId -> !optionIdsOfParam.contains(itemOptionId))
                .collect(Collectors.toList());

            // repeatIdCheckList 若不为空则说明规格选项不重复,可以更新
            Assert.notEmpty(repeatIdCheckList, ErrorCode.SELECT_REPEATED.getCode(),
                ErrorCode.SELECT_REPEATED.getMessage());
        }
    }

    /**
     * 删除服务Sku
     *
     * @param deleteServiceSkuDto
     * @return {@link int}
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long deleteHousekeeperServiceSkuBySkuId(DeleteServiceSkuDto deleteServiceSkuDto) {
        Long skuId = deleteServiceSkuDto.getSkuId();

        // 删除sku
        ServiceSku skuEntity = serviceSkuMapper.selectById(skuId);
        Assert.notNull(skuEntity, ErrorCode.SKU_NOT_EXIST.getCode(), ErrorCode.SKU_NOT_EXIST.getMessage());
        skuEntity.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
        serviceSkuMapper.updateById(skuEntity);

        // 删除sku对应的选项
        LambdaQueryWrapper<ServiceSelection> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ServiceSelection::getSkuId, skuId);
        ServiceSelection updateObj = new ServiceSelection();
        updateObj.setDeleteFlag(DeletedFlagEnum.SERVICE_FLAGE_DELETED.getCode());
        serviceSelectionMapper.update(updateObj, queryWrapper);
        return skuId;
    }

    /**
     * 根据skuid拿到服务详细描述
     *
     * @param getSkuDetailBySkuIdDto
     * @return {@link com.huawei.housekeeper.controller.response.ServiceSkuInfoRespVo}
     */
    @Override
    public ServiceSkuInfoRespVo getSkuDetailBySkuId(GetSkuDetailBySkuIdDto getSkuDetailBySkuIdDto) {
        ServiceSku serviceSku = serviceSkuMapper.selectById(getSkuDetailBySkuIdDto.getSkuId());
        Assert.notNull(serviceSku, ErrorCode.SKU_NOT_EXIST.getCode(), ErrorCode.SKU_NOT_EXIST.getMessage());
        ServiceSkuInfoRespVo serviceSkuInfoRespVo = buildServiceSkuInfoRespVo(serviceSku);
        serviceSkuInfoRespVo.setSelections(getSelectionList(serviceSku));
        return serviceSkuInfoRespVo;
    }

    /**
     * 根据Sku初始化返回结果数据
     *
     * @param serviceSku
     * @return {@link com.huawei.housekeeper.controller.response.ServiceSkuInfoRespVo}
     */
    private ServiceSkuInfoRespVo buildServiceSkuInfoRespVo(ServiceSku serviceSku) {
        HousekeeperService housekeeperService = housekeeperServiceMapper.selectById(serviceSku.getServiceId());
        Assert.notNull(housekeeperService, ErrorCode.SERVICE_NOT_EXIST.getCode(),
            ErrorCode.SERVICE_NOT_EXIST.getMessage());
        ServiceSkuInfoRespVo serviceSkuInfoRespVo = new ServiceSkuInfoRespVo();
        serviceSkuInfoRespVo.setSkuId(serviceSku.getId());
        serviceSkuInfoRespVo.setPrice(serviceSku.getPrice());
        serviceSkuInfoRespVo.setServiceName(housekeeperService.getServiceName());
        serviceSkuInfoRespVo.setServiceDesc(housekeeperService.getServiceDesc());
        serviceSkuInfoRespVo.setServcieId(housekeeperService.getId());
        serviceSkuInfoRespVo.setImgSrc(housekeeperService.getImgSrc());
        return serviceSkuInfoRespVo;
    }

    /**
     * 获取规格服务选集
     *
     * @param serviceSku
     * @return {@link List< ServiceSkuInfoRespVo.OptionProperty>}
     */
    private List<ServiceSkuInfoRespVo.OptionProperty> getSelectionList(ServiceSku serviceSku) {
        // 根据skuId查询服务选集
        LambdaQueryWrapper<ServiceSelection> querySelection = Wrappers.lambdaQuery();
        querySelection.eq(ServiceSelection::getSkuId, serviceSku.getId());
        querySelection.eq(ServiceSelection::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());
        List<ServiceSelection> serviceSelectionList = serviceSelectionMapper.selectList(querySelection);
        Assert.notEmpty(serviceSelectionList, ErrorCode.SERVICE_SELECT_EMPTY.getCode(),
            ErrorCode.SERVICE_SELECT_EMPTY.getMessage());

        // 根据optionId 查询规格选项列表
        List<Long> optionIdList = serviceSelectionList.stream()
            .collect(Collectors.mapping(ServiceSelection::getOptionId, Collectors.toList()));
        List<ServiceOption> serviceOptionList = serviceOptionMapper.selectBatchIds(optionIdList);
        Assert.notEmpty(serviceOptionList, ErrorCode.SPECIFICATION_SELECT_EMPTY.getCode(),
            ErrorCode.SPECIFICATION_SELECT_EMPTY.getMessage());

        // 根据选项ID分组规格选项列表
        Map<Long, ServiceOption> optionIdMap = serviceOptionList.stream()
            .collect(Collectors.toMap(ServiceOption::getId, Function.identity()));
        LambdaQueryWrapper<ServiceSpecification> querySpecification = Wrappers.lambdaQuery();
        querySpecification.eq(ServiceSpecification::getServiceId, serviceSku.getServiceId());
        querySpecification.eq(ServiceSpecification::getDeleteFlag, DeletedFlagEnum.SERVICE_FLAGE_UNDELETED.getCode());

        // 查询该服务下未删除的规格列表
        List<ServiceSpecification> serviceSpecificationList = serviceSpecificationMapper.selectList(querySpecification);
        Assert.notEmpty(serviceSpecificationList, ErrorCode.SPECIFICATION_SELECT_EMPTY.getCode(),
            ErrorCode.SPECIFICATION_SELECT_EMPTY.getMessage());

        // 将规格表映射为Map，可以根据规格id查找规格
        Map<Long, ServiceSpecification> specMapGroupById = serviceSpecificationList.stream()
            .collect(Collectors.toMap(ServiceSpecification::getId, Function.identity(), (key1, key2) -> key2));
        List<ServiceSkuInfoRespVo.OptionProperty> selections = new ArrayList<>();
        serviceSelectionList.forEach(selection -> {
            ServiceSkuInfoRespVo.OptionProperty optionProperty = new ServiceSkuInfoRespVo.OptionProperty();
            optionProperty.setSelectionId(selection.getId());
            optionProperty.setOptionId(selection.getOptionId());
            ServiceOption theOption = optionIdMap.get(selection.getOptionId());

            // 设置选项名称
            optionProperty.setOptionName(theOption.getName());

            // 设置规格名称
            optionProperty.setSpecName(specMapGroupById.get(theOption.getSpecificationId()).getName());
            selections.add(optionProperty);
        });
        return selections;
    }
}